using System;
using System.Runtime.Serialization;

namespace BanZuiCloudControlAgent.Utils.Exceptions
{
    /// <summary>
    /// 任务相关异常类，用于表示任务创建、执行、取消等过程中发生的错误
    /// </summary>
    [Serializable]
    public class TaskException : BanZuiException
    {
        /// <summary>
        /// 任务错误类型
        /// </summary>
        public TaskErrorType ErrorType { get; }

        /// <summary>
        /// 任务ID（如果适用）
        /// </summary>
        public string TaskId { get; }

        /// <summary>
        /// 初始化TaskException类的新实例
        /// </summary>
        public TaskException() : base("E500", "Task", "任务操作发生错误")
        {
            ErrorType = TaskErrorType.Unknown;
            TaskId = null;
        }

        /// <summary>
        /// 使用指定的错误消息初始化TaskException类的新实例
        /// </summary>
        /// <param name="message">描述错误的消息</param>
        public TaskException(string message) : base("E500", "Task", message)
        {
            ErrorType = TaskErrorType.Unknown;
            TaskId = null;
        }

        /// <summary>
        /// 使用指定的错误消息和内部异常初始化TaskException类的新实例
        /// </summary>
        /// <param name="message">描述错误的消息</param>
        /// <param name="innerException">导致当前异常的异常</param>
        public TaskException(string message, Exception innerException) : base("E500", "Task", message, false, innerException)
        {
            ErrorType = TaskErrorType.Unknown;
            TaskId = null;
        }

        /// <summary>
        /// 使用指定的错误类型和消息初始化TaskException类的新实例
        /// </summary>
        /// <param name="errorType">任务错误类型</param>
        /// <param name="message">描述错误的消息</param>
        public TaskException(TaskErrorType errorType, string message) : base(GetErrorCode(errorType), "Task", message)
        {
            ErrorType = errorType;
            TaskId = null;
        }

        /// <summary>
        /// 使用指定的错误类型、消息和内部异常初始化TaskException类的新实例
        /// </summary>
        /// <param name="errorType">任务错误类型</param>
        /// <param name="message">描述错误的消息</param>
        /// <param name="innerException">导致当前异常的异常</param>
        public TaskException(TaskErrorType errorType, string message, Exception innerException) : base(GetErrorCode(errorType), "Task", message, false, innerException)
        {
            ErrorType = errorType;
            TaskId = null;
        }

        /// <summary>
        /// 使用指定的错误类型、任务ID和消息初始化TaskException类的新实例
        /// </summary>
        /// <param name="errorType">任务错误类型</param>
        /// <param name="taskId">任务ID</param>
        /// <param name="message">描述错误的消息</param>
        public TaskException(TaskErrorType errorType, string taskId, string message) : base(GetErrorCode(errorType), "Task", message)
        {
            ErrorType = errorType;
            TaskId = taskId;
        }

        /// <summary>
        /// 使用指定的错误类型、任务ID、消息和内部异常初始化TaskException类的新实例
        /// </summary>
        /// <param name="errorType">任务错误类型</param>
        /// <param name="taskId">任务ID</param>
        /// <param name="message">描述错误的消息</param>
        /// <param name="innerException">导致当前异常的异常</param>
        public TaskException(TaskErrorType errorType, string taskId, string message, Exception innerException) : base(GetErrorCode(errorType), "Task", message, false, innerException)
        {
            ErrorType = errorType;
            TaskId = taskId;
        }

        /// <summary>
        /// 使用序列化数据初始化TaskException类的新实例
        /// </summary>
        /// <param name="info">SerializationInfo，它存有关于所引发的异常的序列化的对象数据</param>
        /// <param name="context">包含有关源或目标的上下文信息</param>
        protected TaskException(SerializationInfo info, StreamingContext context) : base(info, context)
        {
            ErrorType = (TaskErrorType)info.GetInt32("ErrorType");
            TaskId = info.GetString("TaskId");
        }

        /// <summary>
        /// 使用可序列化的数据填充SerializationInfo
        /// </summary>
        /// <param name="info">要填充数据的SerializationInfo</param>
        /// <param name="context">此序列化的目标</param>
        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            base.GetObjectData(info, context);
            info.AddValue("ErrorType", (int)ErrorType);
            info.AddValue("TaskId", TaskId);
        }

        /// <summary>
        /// 获取包含错误代码、任务ID的完整错误消息
        /// </summary>
        /// <returns>包含错误代码、任务ID的完整错误消息</returns>
        public override string ToString()
        {
            if (string.IsNullOrEmpty(TaskId))
            {
                return base.ToString();
            }
            return $"[{ErrorCode}] {Module} (TaskId: {TaskId}): {Message}";
        }

        /// <summary>
        /// 根据任务错误类型获取错误代码
        /// </summary>
        /// <param name="errorType">任务错误类型</param>
        /// <returns>错误代码</returns>
        private static string GetErrorCode(TaskErrorType errorType)
        {
            switch (errorType)
            {
                case TaskErrorType.InvalidTaskType:
                    return "E501";
                case TaskErrorType.TaskNotFound:
                    return "E502";
                case TaskErrorType.TaskCanceled:
                    return "E503";
                case TaskErrorType.TaskFailed:
                    return "E504";
                case TaskErrorType.TaskTimeout:
                    return "E505";
                case TaskErrorType.InvalidParameters:
                    return "E506";
                case TaskErrorType.ExecutionFailed:
                    return "E507";
                case TaskErrorType.TaskAlreadyExists:
                    return "E508";
                default:
                    return "E500";
            }
        }
    }

    /// <summary>
    /// 任务错误类型枚举
    /// </summary>
    public enum TaskErrorType
    {
        /// <summary>
        /// 未知错误
        /// </summary>
        Unknown = 0,

        /// <summary>
        /// 无效的任务类型
        /// </summary>
        InvalidTaskType = 1,

        /// <summary>
        /// 任务未找到
        /// </summary>
        TaskNotFound = 2,

        /// <summary>
        /// 任务已取消
        /// </summary>
        TaskCanceled = 3,

        /// <summary>
        /// 任务失败
        /// </summary>
        TaskFailed = 4,

        /// <summary>
        /// 任务超时
        /// </summary>
        TaskTimeout = 5,

        /// <summary>
        /// 无效的参数
        /// </summary>
        InvalidParameters = 6,

        /// <summary>
        /// 执行失败
        /// </summary>
        ExecutionFailed = 7,

        /// <summary>
        /// 任务已存在
        /// </summary>
        TaskAlreadyExists = 8
    }
} 